package com.example.glgk.optionenum;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;

/**
 * 解决 spring  json 转枚举问题
 * @author liuxingkun
 */
public class OptionsEnumDeserializer extends JsonDeserializer<Enum> implements ContextualDeserializer {

    private Class clazz;

    @Override
    public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {

        JsonToken currentToken = jp.getCurrentToken();

        if (JsonToken.VALUE_STRING.equals(currentToken) && StringUtils.isNotBlank(jp.getText())) {
            return Enum.valueOf(clazz, jp.getText());
        } else if (JsonToken.START_OBJECT.equals(currentToken)) {
            JsonNode node = jp.getCodec().readTree(jp);
            return getEnumValue(node, clazz);
        }

        return null;
    }

    private Enum getEnumValue(JsonNode node, Class clazz) {

        if (node != null) {
            JsonNode valueNode = node.get("value");
            if (valueNode != null && StringUtils.isNotBlank(valueNode.asText())) {
                return Enum.valueOf(clazz, valueNode.asText());
            }
        }

        return null;
    }


    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        Class clazz = ctxt.getContextualType().getRawClass();
        OptionsEnumDeserializer deserializer = new OptionsEnumDeserializer();
        deserializer.setClazz(clazz);
        return deserializer;
    }

    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }
}